//
//  PolyvVideoView.m
//  flutter_polyv_plugin
//
//  Created by 蒋俊 on 2023/11/4.
//

#import "PolyvVideoView.h"
#import <PLVVodSDK/PLVVodSDK.h>

@interface PolyvVideoView()
@property (nonatomic, strong) PLVVodPlayerViewController *videoViewController;
@property (nonatomic, strong) FlutterMethodChannel *channel;
@property (nonatomic, assign) BOOL isBuffering;
@property (nonatomic, strong) NSTimer *timer;
@end

@implementation PolyvVideoView
- (instancetype)initWithFrame:(CGRect)frame
               viewIdentifier:(int64_t)viewId
                    arguments:(id _Nullable)args
              binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
    if (self = [super init]) {
        self.videoViewController = [[PLVVodPlayerViewController alloc] init];
        self.videoViewController.view.frame = frame;
        self.videoViewController.autoplay = NO;
        self.videoViewController.isVideoToolBox = NO;
        self.videoViewController.seekType = PLVVodPlaySeekTypePrecise;
//        self.videoViewController.maxCacheDuration = 1;
        NSString *channelName = [NSString stringWithFormat:@"polyv_video_plugin_%lld", viewId];
        self.channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger];
        __weak __typeof__(self) weakSelf = self;
        [self.channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
            __strong typeof(weakSelf) strongSelf = weakSelf;
            [strongSelf handleMethodCall:call result:result];
        }];
        
        // 是否就绪播放回调
        self.videoViewController.preparedToPlayHandler = ^(PLVVodPlayerViewController *player) {
            __strong typeof(weakSelf) strongSelf = weakSelf;
            if (player.preparedToPlay) {
                [strongSelf.channel invokeMethod:@"initialized" arguments:@{@"initialized":@YES}];
                CGSize size = [player getVideoSize];
                NSNumber *width = [NSNumber numberWithInt:size.width];
                NSNumber *height = [NSNumber numberWithInt:size.height];
                [strongSelf.channel invokeMethod:@"videoSize" arguments:@{@"width": width, @"height": height}];
            }
        };
        
        // 是否加载中回调
        self.videoViewController.loadingHandler = ^(BOOL isLoading) {
            __strong typeof(weakSelf) strongSelf = weakSelf;
            strongSelf.isBuffering = isLoading;
        };
        
        // 播放结束回调
        self.videoViewController.reachEndHandler = ^(PLVVodPlayerViewController *player) {
            if (player.reachEndSuccess) {
                __strong typeof(weakSelf) strongSelf = weakSelf;
                [strongSelf.channel invokeMethod:@"completed" arguments:nil];
            }
        };
        
        // 错误回调
        self.videoViewController.playerErrorHandler = ^(PLVVodPlayerViewController *player, NSError *error) {
            NSLog(@"player error: %@", error);
            if (error.code == 20100) {
                
            }
            NSString *reason = [NSString stringWithFormat:@"%@,%@", error.userInfo[@"NSLocalizedDescription"], error.userInfo[@"NSHelpAnchor"]];
            NSDictionary *dict = @{
                @"code": [NSString stringWithFormat:@"%ld", error.code],
                @"reason" : reason
            };
            __strong typeof(weakSelf) strongSelf = weakSelf;
            [strongSelf->_channel invokeMethod:@"videoPlayError" arguments:dict];
           
        };
        
        // 恢复播放
        self.videoViewController.playbackRecoveryHandle = ^(PLVVodPlayerViewController *player) {
            NSLog(@"playbackRecoveryHandle");
            NSDictionary *dict = @{
                @"type":@"playbackRecoveryHandle",
            };
            __strong typeof(weakSelf) strongSelf = weakSelf;
            [strongSelf->_channel invokeMethod:@"listener" arguments:dict];
        };
        
        // 每秒通知 Dart 缓冲状态与缓冲百分比
        self.timer = [NSTimer timerWithTimeInterval:2 repeats:YES block:^(NSTimer * _Nonnull timer) {
            __strong typeof(weakSelf) strongSelf = weakSelf;
            double bufferPercentage = strongSelf.videoViewController.playableDuration / strongSelf.videoViewController.duration * 100;
            [strongSelf.channel invokeMethod:@"bufferingUpdate" arguments:@{
                @"isBuffering" : [NSNumber numberWithBool: strongSelf.isBuffering],
                @"bufferPercentage" : [NSNumber numberWithInt:bufferPercentage],
            }];
        }];
        [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
    }
    return self;
}

- (void)setVid:(NSString *)vid {
    if (vid != NULL && vid.length > 0) {
        __weak __typeof__(self) weakSelf = self;
        [PLVVodVideo requestVideoPriorityCacheWithVid:vid completion:^(PLVVodVideo *video, NSError *error) {
            __strong typeof(weakSelf) strongSelf = weakSelf;
            // 在线视频播放，默认会优先播放本地视频
            if (error) {
                if (strongSelf.videoViewController.playerErrorHandler) {
                    strongSelf.videoViewController.playerErrorHandler(strongSelf.videoViewController, error);
                };
            } else {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [strongSelf.videoViewController setVideo:video];
                });
            }
        }];
    }
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
    NSDictionary *argsMap = call.arguments;
    if ([[call method] isEqualToString:@"setVid"]) {
        NSString *vid = call.arguments[@"vid"];
        [self setVid:vid];
        result(nil);
    }
    else if ([[call method] isEqualToString:@"setURL"]) {
        NSString *url = argsMap[@"url"];
        [self.videoViewController setURL:[NSURL URLWithString:url]];
        result(nil);
    }
    else if ([[call method] isEqualToString:@"setVideoPath"]) {
        NSString *path = argsMap[@"path"];
        NSURL *url = [NSURL fileURLWithPath:path];
        [self.videoViewController setURL:url];
    }
    else if ([[call method] isEqualToString:@"enableLoop"]) {
        BOOL loop = [argsMap[@"loop"] boolValue];
        self.videoViewController.enablePlayRecycle = loop;
    }
    else if ([[call method] isEqualToString:@"play"]) {
        [self.videoViewController play];
        result(nil);
    }
    else if([[call method] isEqualToString:@"pause"]) {
        [self.videoViewController pause];
        result(nil);
    }
    else if ([[call method] isEqualToString:@"setVideoURI"]) {
        NSString *url = argsMap[@"url"];
        [self.videoViewController setURL:[NSURL URLWithString:url]];
        [self.videoViewController play];
        result(nil);
    }
    else if([[call method] isEqualToString:@"brightness"]) { // 获取亮度
        result([self onBrightness]);
    }
    else if([[call method] isEqualToString:@"volume"]) { // 获取音量
        result([self onGetVolume]);
    }
    else if([[call method] isEqualToString:@"setBrightness"]) { // 设置亮度
        [self onSetBrightness:call result:result];
    }
    else if([[call method] isEqualToString:@"setVolume"]) { // 设置音量
        [self onSetVolume:call result:result];
    }
    else if ([[call method] isEqualToString:@"isPlaying"]) { // 是否播放中
        result(self.videoViewController.playbackState == PLVVodPlaybackStatePlaying ? @YES : @NO);
    }
    else if ([[call method] isEqualToString:@"isBuffering"]) {
        result([NSNumber numberWithBool:self.isBuffering]);
    }
    else if ([[call method] isEqualToString:@"duration"]) { // 总时长
        NSNumber *point = [self getDuration];
        result(point);
    }
    else if ([[call method] isEqualToString:@"currentPosition"]) { // 当前节点
        NSNumber *point = [self getCurrentPlaybackTime];
        result(point);
    }
    else if ([[call method] isEqualToString:@"bufferPercentage"]) { // 缓冲百分比
        NSNumber *point = [self getPlayableDuration];
        result(point);
    }
    else if ([[call method] isEqualToString:@"seekTo"]) {  // 跳转某节点
        NSString *point = argsMap[@"progress"];
        self.videoViewController.currentPlaybackTime = point.doubleValue/1000.0;
        [self.videoViewController play];
        result(nil);
    }
    else if ([[call method] isEqualToString:@"playbackSpeed"]) { // 获取播放速度
        NSNumber *rate = [NSNumber numberWithDouble:self.videoViewController.playbackRate];
        result(rate);
    }
    else if ([[call method] isEqualToString:@"setPlaybackSpeed"]) { // 设置播放速度
        NSString *rate = argsMap[@"speed"];
        self.videoViewController.playbackRate = rate.doubleValue;
        result(nil);
    }
    else {
        result(FlutterMethodNotImplemented);
    }
}

// 总时长
- (NSNumber *)getDuration {
    return [NSNumber numberWithInt:(self.videoViewController.duration*1000)];
}

// 当前节点
- (NSNumber *)getCurrentPlaybackTime {
    return [NSNumber numberWithInt:self.videoViewController.currentPlaybackTime*1000];
}

// 缓冲百分比
- (NSNumber *)getPlayableDuration {
    return [NSNumber numberWithInt: self.videoViewController.playableDuration*100/self.videoViewController.duration];
}

- (NSNumber *)onBrightness {
    float tmp = [UIScreen mainScreen].brightness * 100;
    int a = (int)lroundf(tmp);
    //    DLog(@"[LiveView打印2] 当前亮度>>>>> %d",a);
    return [NSNumber numberWithInt:a];
}

- (void)onSetBrightness:(FlutterMethodCall*)call result:(FlutterResult)result {
    NSDictionary *argsMap = call.arguments;
    int brightness = [argsMap[@"brightness"] intValue];
    float tmp = brightness / 100.0;
    //    DLog(@"[LiveView打印] 亮度settings >>>>> %f",tmp);
    [[UIScreen mainScreen] setBrightness:tmp];
}

- (NSNumber *)onGetVolume {
    double volume = self.videoViewController.playbackVolume * 100;
    NSNumber *volumeNumber = [NSNumber numberWithInt:volume];
    return volumeNumber;
}

- (void)onSetVolume:(FlutterMethodCall*)call result:(FlutterResult)result {
    NSDictionary *argsMap = call.arguments;
    int volumeValue = [argsMap[@"volume"] intValue];
    if (volumeValue > 100) volumeValue = 100;
    if (volumeValue < 0) volumeValue = 0;
    double tmp = volumeValue / 100.0;
    self.videoViewController.playbackVolume = tmp;
}


- (nonnull UIView *)view {
    return self.videoViewController.view;
}

- (void)dealloc {
    [self.videoViewController destroyPlayer];
    [self.timer invalidate];
    self.timer = nil;
    NSLog(@"PolyvVideoView dealloc");
}

@end
